package com.xzh.mallorderapi.config;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.xzh.mallorderapi.util.SpringUtils;
import feign.RequestInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StringUtils;

@EnableAspectJAutoProxy(exposeProxy = true)
@EnableTransactionManagement
@Configuration
public class Config {
    @Value("${datacenter-id}")
    private Integer datacenterId;//数据中心编号
    @Value("${worker-id}")
    private Integer workerId;//主机编号

    //mybatis-plus分页插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

    //雪花算法生成器
    @Bean
    public Snowflake snowflake() {
        return IdUtil.getSnowflake(workerId, datacenterId);
    }

    /**
     * 自定义json序列化器
     *
     * @return 自定义json序列化器
     */
    @Bean
    public Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
        //克隆一个新的ObjectMapper实例
        ObjectMapper om = new ObjectMapper();
        //添加对jdk8日期类型的支持，需要在pom文件中引入jackson-datatype-jsr310，spring-boot-starter-web已默认引入
        om.registerModule(new JavaTimeModule());
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //必须进行以下配置，否则会出现java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to xxx的异常
        //详见：https://knife.blog.csdn.net/article/details/122427607
        //配置在序列化时，将类型序列化到json中，所以能在反序列化时，自动根据类型进行反序列化
        om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        //配置对于无法反序列化的字段，不报错。比如有getter方法，但无setter方法或者无对应字段，则在反序列化时，不报错
        om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值（默认使用JDK的序列化方式：JdkSerializationRedisSerializer）
        return new Jackson2JsonRedisSerializer<>(om, Object.class);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory, Jackson2JsonRedisSerializer<Object> valueSerializer) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setValueSerializer(valueSerializer);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }


    // @Bean
    // @Primary
    // public RocketMQMessageConverter customizeRocketMQMessageConverter() {
    //     RocketMQMessageConverter converter = new RocketMQMessageConverter();
    //     //获取内部的CompositeMessageConverter并遍历找到MappingJackson2MessageConverter
    //     CompositeMessageConverter compositeConverter = (CompositeMessageConverter) converter.getMessageConverter();
    //
    //     for (MessageConverter messageConverter : compositeConverter.getConverters()) {
    //         if (messageConverter instanceof MappingJackson2MessageConverter jackson2MessageConverter) {
    //             ObjectMapper objectMapper = jackson2MessageConverter.getObjectMapper();
    //             // 注册 JavaTimeModule 以支持 LocalDateTime 等 Java 8 时间类型[1](@ref)
    //             objectMapper.registerModule(new JavaTimeModule());
    //             //禁用将日期序列化为时间戳，使其输出更可读的字符串格式（如 "2025-09-02T22:36:19"）
    //             objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    //         }
    //     }
    //     return converter;
    // }

    //为每个feign调用添加请求头
    @Bean
    public RequestInterceptor requestInterceptor() {
        return template -> {
            //从当前线程中取出request对象
            HttpServletRequest req = SpringUtils.getServletRequest();

            //获取请求头中的jwt
            String jwt = req.getHeader("Authorization");
            if (!StringUtils.hasText(jwt)) {
                jwt = req.getParameter("jwt");
            }

            //继续向下游调用传递请求头
            if (StringUtils.hasText(jwt)) {
                template.header("Authorization", jwt);
            }
        };
    }
}

